1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 
12 module hip.api.graphics.g2d.renderer2d;
13 
14 import hip.api.internal;
15 public import hip.api.data.image;
16 public import hip.api.graphics.color;
17 public import hip.api.renderer.texture;
18 public import hip.api.data.font;
19 public import hip.api.graphics.text;
20 public import hip.api.graphics.g2d.animation;
21 public import hip.api.graphics.g2d.g2d_binding;
22 
23 version(ScriptAPI)
24 {
25 	version = DefineOverloadings;
26 	version(Have_util) version = DefineCreateFromAtlas;
27 }
28 
29 
30 version(DefineOverloadings)
31 {
32 	private alias G2D = hip.api.graphics.g2d.g2d_binding;
33 	///Sets the font for the next drawText commands
34 	void setFont(IHipFont font){G2D.setFont(font);}
35 	void setFont(typeof(null)){G2D.setFont(cast(IHipFont)null);}
36 
37 	//Float overloading for drawLine
38 	void drawLine(float x1, float y1, float x2, float y2, HipColor color = HipColor.no)
39 	{
40 		hip.api.graphics.g2d.g2d_binding.drawLine(cast(int)x1, cast(int)y1, cast(int)x2, cast(int)y2, color);
41 	}
42 	void drawRectangle(float x, float y, float width, float height, HipColor color = HipColor.no)
43 	{
44 		hip.api.graphics.g2d.g2d_binding.drawRectangle(cast(int)x, cast(int)y, cast(int)width, cast(int)height, color);
45 	}
46 
47 	///Circle API
48 		void drawCircle(int x, int y, int radius, HipColor color = HipColor.no, int precision = 24)
49 		{
50 			hip.api.graphics.g2d.g2d_binding.drawEllipse(x, y, radius, radius, 360, color, precision);
51 		}
52 		void drawCircle(float x, float y, float radius, HipColor color = HipColor.no, int precision = 24)
53 		{
54 			hip.api.graphics.g2d.g2d_binding.drawEllipse(cast(int)x, cast(int)y, cast(int)radius, cast(int)radius, 360, color, precision);
55 		}
56 
57 		void fillCircle(int x, int y, int radius, HipColor color = HipColor.no, int precision = 24)
58 		{
59 			hip.api.graphics.g2d.g2d_binding.fillEllipse(cast(int)x, cast(int)y, cast(int)radius, cast(int)radius, 360, color, precision);
60 		}
61 		void fillCircle(float x, float y, float radius, HipColor color = HipColor.no, int precision = 24)
62 		{
63 			hip.api.graphics.g2d.g2d_binding.fillEllipse(cast(int)x, cast(int)y, cast(int)radius, cast(int)radius, 360, color, precision);
64 		}
65 	///
66 
67 	///Float overloading for fillEllipse
68 	void fillEllipse(float x, float y, float width, float height, int degrees = 360,  HipColor color = HipColor.no, int precision = 24)
69 	{
70 		hip.api.graphics.g2d.g2d_binding.fillEllipse(cast(int)x, cast(int)y, cast(int)width, cast(int)height, degrees, color, precision);
71 	}
72 
73 	///Float overloading for drawEllipse
74 	void drawEllipse(float x, float y, float width, float height, int degrees = 360, HipColor color = HipColor.no, int precision = 24)
75 	{
76 		hip.api.graphics.g2d.g2d_binding.drawEllipse(cast(int)x, cast(int)y, cast(int)width, cast(int)height, degrees, color, precision);
77 	}
78 
79 	///Float overloading for fillRectangle
80 	void fillRectangle(float x, float y, float width, float height, HipColor color = HipColor.no)
81 	{
82 		hip.api.graphics.g2d.g2d_binding.fillRectangle(cast(int)x, cast(int)y, cast(int)width, cast(int)height, color);
83 	}
84 
85 	version(Have_util)
86 	{
87 		import hip.util.reflection:isTypeArrayOf;
88 
89 		pragma(inline, true)
90 		{
91 			//Struct compatible with float[2] or float[2]
92 			void drawLine(T)(in T start, in T end, HipColor color = HipColor.no)
93 			if(isTypeArrayOf!(float, T, 2))
94 			{
95 				const float[2] s = *cast(const(float[2])*)cast(const(void*))&start;
96 				const float[2] e = *cast(const(float[2])*)cast(const(void*))&end;
97 				drawLine(s[0], s[1], e[0], e[1], color);
98 			}
99 			///Struct compatible with float[4] or float[4]
100 			void fillRectangle(T)(in T r, HipColor color = HipColor.no)
101 			if(isTypeArrayOf!(float, T, 4))
102 			{
103 				const float[4] a = *cast(const(float[4]*))cast(const(void*))&r;
104 				fillRectangle(a[0], a[1], a[2], a[3], color);
105 			}
106 			void drawRectangle(T)(in T r, HipColor color = HipColor.no)
107 			if(isTypeArrayOf!(float, T, 4))
108 			{
109 				const float[4] a = *cast(const(float[4]*))cast(const(void*))&r;
110 				drawRectangle(a[0], a[1], a[2], a[3], color);
111 			}
112 		}
113 		
114 		///Rect overload for fillRectangle
115 	}
116 }
117 
118 version(DefineCreateFromAtlas)
119 {
120 	/**
121 	*   Creates an IHipAnimation from a loaded texture atlas.
122 	*   Its frames will be checked such as `mySprite${frameNumber}`.
123 	*   The animation will be named as the string without the number.
124 	*/
125 	static IHipAnimation createFromAtlas(IHipTextureAtlas atlas, string animationName, uint framesPerSecond = 24)
126 	{
127 		import hip.util.string:getNumericEnding, lastIndexOf;
128 		import hip.util.algorithm;
129 		import hip.api.graphics.g2d.renderer2d;
130 		import std.algorithm:sort;
131 
132 		IHipAnimation anim = newHipAnimation(animationName);
133 		foreach(string frameName; sort(atlas.frames.keys))
134 		{
135 			AtlasFrame* frame = frameName in atlas;
136 			string name = frameName;
137 			int index = frameName.lastIndexOf(frameName.getNumericEnding);
138 			if(index != -1)
139 				name = frameName[0..index];
140 			IHipAnimationTrack track = anim.getTrack(name);
141 			if(track is null)
142 			{
143 				anim.addTrack(track = newHipAnimationTrack(name, framesPerSecond, HipAnimationLoopingMode.reset));
144 			}
145 			track.addFrames(HipAnimationFrame(frame.region, HipColor.white, [0,0]));
146 
147 		}
148 		return anim;
149 	}
150 }